/*
Copyright (c) 2010 Andreas Bjerkeholt
License: MIT
http://www.opensource.org/licenses/mit-license.php
*/
#ifndef __global_h__
#define __global_h__

#include <stdint.h>
#include <stdbool.h>
#include <sml/graphics.h>

#define max(x, y) (x > y ? x : y)
#define min(x, y) (x < y ? x : y)
#define SAFE_FREE(p) { if (p) {free(p); p = 0;}}

#define TILESIZE 24
#define HUDTILESIZE 16

#define GAME_MODE_SPLASH  1
#define GAME_MODE_MENU    2
#define GAME_MODE_GAME    3
#define GAME_MODE_ERROR   4
#define GAME_MODE_VICTORY 5

#define GAME_MODE_MENU_MAIN         1
#define GAME_MODE_MENU_LEVELLIST    2
#define GAME_MODE_MENU_INSTRUCTIONS 3
#define GAME_MODE_MENU_CONTROLS     4
#define GAME_MODE_MENU_OPTIONS      5
#define GAME_MODE_MENU_CREDITS      6

#define GAME_MODE_GAME_SPLASH      1
#define GAME_MODE_GAME_PLAY        2
#define GAME_MODE_GAME_WON         4
#define GAME_MODE_GAME_GAMEOVER    5
#define GAME_MODE_GAME_PASSWORD    7

extern uint8_t gameMode;
extern uint8_t gameModeSub;

#define EXIT_SAVING  0
#define EXIT_EXITING 1

#define CONFIG_SOUND_ON      0
#define CONFIG_SOUND_REDUCED 1
#define CONFIG_SOUND_OFF     2
#define CONFIG_MUSIC_ON      0
#define CONFIG_MUSIC_OFF     1

extern uint8_t configVolume;
extern uint8_t configSound;
extern uint8_t configMusic;
extern uint8_t configLastLevel;

extern bool exitConfirmDialog;

extern int8_t playerX;
extern int8_t playerY;

typedef struct {
	uint8_t    type;
	uint8_t    x, y;
	uint8_t    direction;
	bool       sliding;
	uint8_t    moving; // For tanks
	bool       spawning;
} monster;

#define MOVING_STOPPED    0
#define MOVING_SHOULDMOVE 1
#define MOVING_MOVING     2

typedef struct {
	uint8_t    x;
	uint8_t    y;
} position;

typedef struct {
	uint8_t    direction;
	uint8_t    x, y;
} sliding;

typedef struct {
	uint8_t    buttonX;
	uint8_t    buttonY;
	uint8_t    cloneX;
	uint8_t    cloneY;
} cloneCon;

typedef struct {
	uint16_t   buttonX;
	uint16_t   buttonY;
	uint16_t   trapX;
	uint16_t   trapY;
	bool       open;
} trapCon;

typedef struct {
	uint16_t   number;
	char       name[64];
	char       hint[128];
	char       password[10];
	uint8_t    tiles_layer1[1024];
	uint8_t    tiles_layer2[1024];
	uint16_t   spawn_x;
	uint16_t   spawn_y;
	uint16_t   chipsNeeded;
	uint16_t   timeLimit;
	monster    monsters[128];
	bool       completed;
	bool       skipped;
	cloneCon   cloneConnections[31];
	uint16_t   numberOfTeleports;
	uint16_t*  teleports;
	trapCon    trapControls[19];
} level;

typedef struct {
	uint16_t   trapX;
	uint16_t   trapY;
	bool       open;
} trap;

typedef struct {
	uint16_t   buttonX;
	uint16_t   buttonY;
	uint8_t    trapIndex;
} trapBut;

typedef struct {
	uint32_t   time_bonus;
	uint32_t   level_bonus;
	uint32_t   level_score;
	uint32_t   time;
	uint32_t   time_previous;
} score;

extern level*   cur_level;
extern level*   levels;
extern uint16_t numberOfLevels;

extern uint16_t gameTimeLeft;
extern uint16_t gameLevelNo;
extern uint16_t gameChipsLeft;

extern char*    gameOverReason;

extern char*    gameOverMessageTime;
extern char*    gameOverMessageWater;
extern char*    gameOverMessageFire;
extern char*    gameOverMessageMonster;
extern char*    gameOverMessageBlock;
extern char*    gameOverMessageBomb;

extern uint8_t  haveKeysRed;
extern uint8_t  haveKeysBlue;
extern uint8_t  haveKeysYellow;
extern uint8_t  haveKeysGreen;
extern bool     haveFlippers;
extern bool     haveFireBoots;
extern bool     haveIceSkates;
extern bool     haveSuctionBoots;

extern char     pwText[];
extern uint8_t  pwSelected;
extern uint8_t  pwLetterWidth;
extern uint8_t  pwWrong;

#define MONSTER_NONE       0
#define MONSTER_BUG        1
#define MONSTER_FIREBALL   2
#define MONSTER_PINKBALL   3
#define MONSTER_TANK       4
#define MONSTER_GLIDER     5
#define MONSTER_TEETH      6
#define MONSTER_WALKER     7
#define MONSTER_BLOB       8
#define MONSTER_PARAMECIUM 9

extern uint8_t monsterBaseTile[];

#define DIRECTION_NORTH 0
#define DIRECTION_WEST  1
#define DIRECTION_SOUTH 2
#define DIRECTION_EAST  3

#define NUMBER_OF_TILES      0x70
#define TILE_FLOOR           0x00
#define TILE_WALL            0x01
#define TILE_CHIP            0x02
#define TILE_WATER           0x03
#define TILE_FIRE            0x04
#define TILE_INVISIBLE_WALL  0x05
#define TILE_BLOCKED_N       0x06
#define TILE_BLOCKED_W       0x07
#define TILE_BLOCKED_S       0x08
#define TILE_BLOCKED_E       0x09
#define TILE_MOVABLE_BLOCK   0x0A
#define TILE_DIRT            0x0B
#define TILE_ICE             0x0C
#define TILE_FORCE_S         0x0D
#define TILE_CLONE_BLOCK_N   0x0E
#define TILE_CLONE_BLOCK_W   0x0F
#define TILE_CLONE_BLOCK_S   0x10
#define TILE_CLONE_BLOCK_E   0x11
#define TILE_FORCE_N         0x12
#define TILE_FORCE_E         0x13
#define TILE_FORCE_W         0x14
#define TILE_EXIT            0x15
#define TILE_BLUE_DOOR       0x16
#define TILE_RED_DOOR        0x17
#define TILE_GREEN_DOOR      0x18
#define TILE_YELLOW_DOOR     0x19
#define TILE_ICE_CORNER_SE   0x1A
#define TILE_ICE_CORNER_SW   0x1B
#define TILE_ICE_CORNER_NW   0x1C
#define TILE_ICE_CORNER_NE   0x1D
#define TILE_BLUE_BLOCK_F    0x1E
#define TILE_BLUE_BLOCK_R    0x1F
// 0x20 NOT USED
#define TILE_THIEF           0x21
#define TILE_SOCKET          0x22
#define TILE_TOGGLE_BUTTON   0x23
#define TILE_CLONE_BUTTON    0x24
#define TILE_TOGGLE_CLOSED   0x25
#define TILE_TOGGLE_OPEN     0x26
#define TILE_TRAP_BUTTON     0x27
#define TILE_TANK_BUTTON     0x28
#define TILE_TELEPORT        0x29
#define TILE_BOMB            0x2A
#define TILE_TRAP            0x2B
#define TILE_HIDDEN_WALL     0x2C
#define TILE_GRAVEL          0x2D
#define TILE_RECESSED_WALL   0x2E
#define TILE_HINT            0x2F
#define TILE_BLOCKED_SE      0x30
#define TILE_CLONE_MACHINE   0x31
#define TILE_FORCE_RANDOM    0x32
#define TILE_DROWNING_CHIP   0x33
#define TILE_BURNED_CHIP     0x34
// 0x35 - 0x3B NOT USED
#define TILE_SWIMMING_N      0x3C
#define TILE_SWIMMING_W      0x3D
#define TILE_SWIMMING_S      0x3E
#define TILE_SWIMMING_E      0x3F
#define TILE_BUG_N           0x40
#define TILE_BUG_W           0x41
#define TILE_BUG_S           0x42
#define TILE_BUG_E           0x43
#define TILE_FIRE_BUG_N      0x44
#define TILE_FIRE_BUG_W      0x45
#define TILE_FIRE_BUG_S      0x46
#define TILE_FIRE_BUG_E      0x47
#define TILE_PINK_BALL_N     0x48
#define TILE_PINK_BALL_W     0x49
#define TILE_PINK_BALL_S     0x4A
#define TILE_PINK_BALL_E     0x4B
#define TILE_TANK_N          0x4C
#define TILE_TANK_W          0x4D
#define TILE_TANK_S          0x4E
#define TILE_TANK_E          0x4F
#define TILE_GLIDER_N        0x50
#define TILE_GLIDER_W        0x51
#define TILE_GLIDER_S        0x52
#define TILE_GLIDER_E        0x53
#define TILE_TEETH_N         0x54
#define TILE_TEETH_W         0x55
#define TILE_TEETH_S         0x56
#define TILE_TEETH_E         0x57
#define TILE_WALKER_N        0x58
#define TILE_WALKER_W        0x59
#define TILE_WALKER_S        0x5A
#define TILE_WALKER_E        0x5B
#define TILE_BLOB_N          0x5C
#define TILE_BLOB_W          0x5D
#define TILE_BLOB_S          0x5E
#define TILE_BLOB_E          0x5F
#define TILE_PARAMECIUM_N    0x60
#define TILE_PARAMECIUM_W    0x61
#define TILE_PARAMECIUM_S    0x62
#define TILE_PARAMECIUM_E    0x63
#define TILE_BLUE_KEY        0x64
#define TILE_RED_KEY         0x65
#define TILE_GREEN_KEY       0x66
#define TILE_YELLOW_KEY      0x67
#define TILE_FLIPPERS        0x68
#define TILE_FIRE_BOOTS      0x69
#define TILE_ICE_SKATES      0x6A
#define TILE_SUCTION_BOOTS   0x6B
#define TILE_PLAYER_N        0x6C
#define TILE_PLAYER_W        0x6D
#define TILE_PLAYER_S        0x6E
#define TILE_PLAYER_E        0x6F

typedef struct {
	uint16_t	x, y;
	int16_t		xs, ys;
	gfx_color	colorpri, colorsec;
	uint16_t	ttl;
} spark;

typedef struct {
	bool		active;
	uint16_t	x, y;
	int16_t		xs, ys;
	uint16_t	ttl;
	uint8_t		delay;
	spark		sparks[10];
} rocket;

#define NMBR_OF_ROCKETS 4
extern rocket rockets[];

extern uint32_t creditsAnimCounter;

typedef struct {
	char*		header;
	uint8_t		nmbrOfNames;
	char*		names[5];
} credit;

extern credit credits[];
extern uint8_t creditsSize;

extern uint8_t victoryFade;

#define SKIPPABLE_LEVELS 5
uint16_t numberOfSkippedLevels();
bool isCurLevelSkippable();

#endif
